"""
practice IPC
1. Pipe
    pipe() returns a pair of connection objects.
    each connection object has send() and recv() methods.
2. Queue
3. File
4. Socket
5. Event
6. Shared memory
"""
from multiprocessing import Process, Pipe, Queue, \
    Lock, Array, Value


# use pipe and queue for exchanging objects between processes
def ipc_pipe(conn):
    conn.send(['hello', 'world'])
    conn.close()

def ipc_queue(i, q):
    q.put(i)


# use lock for synchronization between processes
def ipc_lock(l, i):
    l.acquire()
    try:
        print(f"hello {i}")
    finally:
        l.release()


# use sharing state between processes
def ipc_sharing_state(n, a):
    n.value = 3.1415
    for i in range(len(a)):
        a[i] += 1


if __name__ == "__main__":
    parent_conn, child_conn = Pipe()
    p_pipe = Process(target=ipc_pipe, args=(child_conn,))
    p_pipe.start()
    print(parent_conn.recv())
    p_pipe.join()

    q = Queue()
    queue_thread_array = []
    for i in range(4):
        p_queue = Process(target=ipc_queue, args=(i, q))
        p_queue.start()
        queue_thread_array.append(p_queue)
    for p in queue_thread_array:
        p.join()
    while True:
        if not q.empty():
            print(q.get())
        else:
            break

    lock = Lock()
    for i in range(5):
        p_lock = Process(target=ipc_lock, args=(lock, i))
        p_lock.start()

    num = Value('d', 0.0)
    array = Array('i', range(5))
    p_sharing_state = Process(target=ipc_sharing_state, args=(num, array))
    p_sharing_state.start()
    p_sharing_state.join()
    print(num.value)
    print(array[:])